package com.nhim.cms.admin.server;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.nhim.cms.admin.client.rpc.TemplateRPCService;
import com.nhim.cms.admin.shared.ETemplateType;
import com.nhim.cms.admin.shared.TemplateRPCProxy;
import com.nhim.cms.admin.shared.TemplateResourceProxy;
import com.nhim.cms.domain.ContentType;
import com.nhim.cms.domain.Template;
import com.nhim.cms.util.ContentTypeManager;
import com.nhim.cms.util.TemplateManager;
import com.nhim.core.AppSettings;
import com.nhim.core.io.PathHelper;

public class TemplateRPCServiceImpl extends RemoteServiceServlet implements
		TemplateRPCService {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	public String persitTemplate(TemplateRPCProxy templateProxy)
			throws IllegalArgumentException {
		ETemplateType type = ETemplateType.get(templateProxy.getType());
		String validation = "";
		Template template;
		switch (type) {
		case GROUP_TEMPLATE:
			if (templateProxy.getId() == 0
					&& TemplateManager.getInstance().findGroupTemplateByName(
							templateProxy.getName()) != null) {
				return "Template exist";
			}
			break;
		case SITE_TEMPLATE:
			if (templateProxy.getId() == 0
					&& TemplateManager.getInstance().findSiteTemplateByName(
							templateProxy.getName()) != null) {
				return "Template exist";
			}
		case CONTENT_TEMPLATE:
			if (templateProxy.getId() == 0
					&& TemplateManager.getInstance().findContentTemplateByName(
							templateProxy.getId(), templateProxy.getName()) != null) {
				return "Template exist";
			}
		}
		template = toTemplate(templateProxy);
		try {
			Template templateResult = TemplateManager.getInstance()
					.saveOrUpdate(template);
			try {
				String templateDirPath = PathHelper.combine(new String[] {
						AppSettings.getInstance().getTemplatesPath(),
						templateResult.getId().toString() });
				File folder = new File(templateDirPath);
				if (!folder.exists())
					folder.mkdirs();
				File filePath = new File(PathHelper.combine(new String[] {
						folder.getPath(), "Template.html" }));
				File cssPath = new File(PathHelper.combine(new String[] {
						folder.getPath(), "Template.css" }));
				if (!filePath.exists() && !cssPath.exists()) {
					Writer fileOut = new OutputStreamWriter(
							new FileOutputStream(filePath), AppSettings
									.getInstance().getEncoding());
					Writer cssOut = new OutputStreamWriter(
							new FileOutputStream(cssPath), AppSettings
									.getInstance().getEncoding());
					try {
						fileOut.write("<!--This is a template file -->");
						cssOut.write("/* This is a CSS document */");

					} finally {
						fileOut.close();
						cssOut.close();
					}
				}

			} catch (Exception ex) {
				ex.printStackTrace();
			}

			return "succeeded!" + templateResult.getId();
		} catch (Exception e) {
			e.printStackTrace();
			validation = e.getMessage();
		}

		return validation;
	}

	private TemplateRPCProxy toRPCProxy(Template template) {
		ContentType contentType = template.getContentType();
		Integer contentTypeId = 0;
		if (contentType != null)
			contentTypeId = contentType.getId();
		TemplateRPCProxy proxy = new TemplateRPCProxy(template.getId(),
				template.getName(), template.getGroupTemplateId(),
				template.getSiteTemplateId(), template.getVersion(),
				template.getIsDefault(), contentTypeId, template.getType());
		return proxy;

	}

	private Template toTemplate(TemplateRPCProxy proxy) {
		Template template;
		if (proxy.getId() == 0)
			template = new Template();
		else
			template = TemplateManager.getInstance().findById(proxy.getId());
		try {
			template.setGroupTemplateId(proxy.getGroupTemplateId());
			template.setIsDefault(proxy.getIsDefault());
			template.setName(proxy.getName());
			template.setSiteTemplateId(proxy.getSiteTemplateId());
			template.setType(proxy.getType());
			template.setVersion(proxy.getVersion());
			if (proxy.getContentTypeId() != null
					&& proxy.getContentTypeId() != 0)
				template.setContentType(ContentTypeManager.getInstance()
						.findById(proxy.getContentTypeId()));
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return template;

	}

	@Override
	public List<TemplateRPCProxy> findAllGroupTemplate()
			throws IllegalArgumentException {
		List<TemplateRPCProxy> listTemplateProxy = new ArrayList<TemplateRPCProxy>();
		List<Template> result = TemplateManager.getInstance()
				.findAllGroupTemplate();
		if (result != null) {
			for (Template template : result)
				listTemplateProxy.add(toRPCProxy(template));
		}
		return listTemplateProxy;
	}

	@Override
	public List<TemplateRPCProxy> findAllSiteTemplate()
			throws IllegalArgumentException {
		List<TemplateRPCProxy> listTemplateProxy = new ArrayList<TemplateRPCProxy>();
		List<Template> result = TemplateManager.getInstance()
				.findAllSiteTemplate();
		if (result != null) {
			for (Template template : result)
				listTemplateProxy.add(toRPCProxy(template));
		}
		return listTemplateProxy;
	}

	@Override
	public List<TemplateRPCProxy> findAllContentTemplateTemplate(
			Integer contentId) throws IllegalArgumentException {
		List<TemplateRPCProxy> listTemplateProxy = new ArrayList<TemplateRPCProxy>();
		List<Template> result = TemplateManager.getInstance()
				.findContentTemplateById(contentId);
		if (result != null) {
			for (Template template : result)
				listTemplateProxy.add(toRPCProxy(template));
		}
		return listTemplateProxy;
	}

	@Override
	public Boolean remove(Integer Id) throws IllegalArgumentException {
		return TemplateManager.getInstance().remove(Id);
	}

	@Override
	public List<TemplateResourceProxy> findAllResources(Integer templateId)
			throws IllegalArgumentException {
		List<TemplateResourceProxy> result = new ArrayList<TemplateResourceProxy>();
		String templateDirPath = PathHelper.combine(new String[] {
				AppSettings.getInstance().getTemplatesPath(),
				templateId.toString() });
		File folder = new File(templateDirPath);
		if (!folder.exists())
			folder.mkdirs();
		File[] listOfFiles = folder.listFiles();
		for (int i = 0; i < listOfFiles.length; i++) {
			File file = listOfFiles[i];
			if (file.isFile()
					&& !file.getName().equalsIgnoreCase("Template.html")
					&& !file.getName().endsWith("Template.css")) {
				TemplateResourceProxy proxy = new TemplateResourceProxy(
						file.getName(), String.valueOf(file.length()) + " KB");
				result.add(proxy);
			}
		}
		return result;

	}

	@Override
	public Boolean removeResource(Integer Id, String fileName)
			throws IllegalArgumentException {
		String path = PathHelper.combine(new String[] {
				AppSettings.getInstance().getTemplatesPath(), Id.toString(),
				fileName });
		File file = new File(path);
		try {
			file.delete();
		} catch (SecurityException ex) {
			return false;
		}
		return true;
	}

	private boolean isAsciiText(String fileName) throws IOException {

		InputStream in = new FileInputStream(fileName);
		byte[] bytes = new byte[500];

		in.read(bytes, 0, bytes.length);
		short bin = 0;

		for (byte thisByte : bytes) {
			char it = (char) thisByte;
			if (!Character.isWhitespace(it) && Character.isISOControl(it)) {

				bin++;
			}
			if (bin >= 5) {
				return false;
			}
		}
		in.close();
		return true;
	}

	@Override
	public List<TemplateResourceProxy> findEditableResoures(Integer templateId)
			throws IllegalArgumentException {
		List<TemplateResourceProxy> result = new ArrayList<TemplateResourceProxy>();
		String templateDirPath = PathHelper.combine(new String[] {
				AppSettings.getInstance().getTemplatesPath(),
				templateId.toString() });
		File folder = new File(templateDirPath);
		if (!folder.exists())
			folder.mkdirs();
		File[] listOfFiles = folder.listFiles();
		for (int i = 0; i < listOfFiles.length; i++) {
			File file = listOfFiles[i];
			try {
				if (file.isFile() && isAsciiText(file.getPath())
						|| file.getName().equalsIgnoreCase("Template.html")
						|| file.getName().equalsIgnoreCase("Template.css")) {
					TemplateResourceProxy proxy = new TemplateResourceProxy();
					proxy.setFileName(file.getName());
					result.add(proxy);
				}
			} catch (IOException e) {

				e.printStackTrace();
			}
		}
		return result;

	}

	@Override
	public String retrieveContent(Integer templateId,
			String filename) throws IllegalArgumentException {
		String path = PathHelper.combine(new String[] {
				AppSettings.getInstance().getTemplatesPath(),
				templateId.toString(), filename });
		File file = new File(path);
		StringBuilder text = new StringBuilder();
		String NL = System.getProperty("line.separator");
		if (file.exists()) {
			Scanner scanner = null;
			try {
				scanner = new Scanner(new FileInputStream(file), AppSettings
						.getInstance().getEncoding());
				while (scanner.hasNextLine()) {
					text.append(scanner.nextLine() + NL);
				}
			}catch(Exception ex)
			{
				ex.printStackTrace();
			}
			finally {
				if(scanner != null)
					scanner.close();
			}
		}
		return text.toString();
	}

	@Override
	public Boolean saveFile(Integer templateId, String content, String fileName)
			throws IllegalArgumentException {
		String path = PathHelper.combine(new String[] {
				AppSettings.getInstance().getTemplatesPath(),
				templateId.toString(), fileName });
		File file = new File(path);
		Writer writer = null;
		Boolean result= true;
		try {
			 writer = new OutputStreamWriter(new FileOutputStream(file), AppSettings.getInstance().getEncoding());
			 writer.write(content);
		} catch (UnsupportedEncodingException e) {
			result = false;
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			result = false;
			e.printStackTrace();
		} catch (IOException e) {
			result = false;
			e.printStackTrace();
		}finally
		{
			if(writer != null)
				try {
					writer.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
		return result;
	}
}
